package network

import (
	"fmt"
	"sync"
	"time"
)

// InstanceStatus 实例状态
type InstanceStatus int

const (
	StatusStopped InstanceStatus = iota
	StatusRunning
	StatusError
)

func (s InstanceStatus) String() string {
	switch s {
	case StatusStopped:
		return "已停止"
	case StatusRunning:
		return "运行中"
	case StatusError:
		return "错误"
	default:
		return "未知"
	}
}

// MarshalJSON 实现JSON序列化
func (s InstanceStatus) MarshalJSON() ([]byte, error) {
	switch s {
	case StatusStopped:
		return []byte(`"stopped"`), nil
	case StatusRunning:
		return []byte(`"running"`), nil
	case StatusError:
		return []byte(`"error"`), nil
	default:
		return []byte(`"unknown"`), nil
	}
}

// ClientInstance 客户端实例
type ClientInstance struct {
	ID        string         `json:"id"`
	Name      string         `json:"name"`
	Host      string         `json:"host"`
	Port      string         `json:"port"`
	Protocol  string         `json:"protocol"`
	Status    InstanceStatus `json:"status"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
	Client    *Client        `json:"-"`
	Error     string         `json:"error"`
}

// ServerInstance 服务端实例
type ServerInstance struct {
	ID        string         `json:"id"`
	Name      string         `json:"name"`
	Port      string         `json:"port"`
	Protocol  string         `json:"protocol"`
	Status    InstanceStatus `json:"status"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
	Server    *Server        `json:"-"`
	Error     string         `json:"error"`
}

// TransferInstance 转发实例
type TransferInstance struct {
	ID         string         `json:"id"`
	Name       string         `json:"name"`
	LocalHost  string         `json:"local_host"`
	LocalPort  string         `json:"local_port"`
	TargetHost string         `json:"target_host"`
	TargetPort string         `json:"target_port"`
	Protocol   string         `json:"protocol"`
	Status     InstanceStatus `json:"status"`
	CreatedAt  time.Time      `json:"created_at"`
	UpdatedAt  time.Time      `json:"updated_at"`
	Transfer   *Transfer      `json:"-"`
	Error      string         `json:"error"`
	// 统计信息
	Connections      int64 `json:"connections"`
	BytesTransferred int64 `json:"bytes_transferred"`
}

// NetworkManager 网络管理器
type NetworkManager struct {
	mutex sync.RWMutex

	clients   map[string]*ClientInstance
	servers   map[string]*ServerInstance
	transfers map[string]*TransferInstance

	// 事件回调
	OnClientEvent   func(instance *ClientInstance, event string, data interface{})
	OnServerEvent   func(instance *ServerInstance, event string, data interface{})
	OnTransferEvent func(instance *TransferInstance, event string, data interface{})
}

// NewNetworkManager 创建新的网络管理器
func NewNetworkManager() *NetworkManager {
	return &NetworkManager{
		clients:   make(map[string]*ClientInstance),
		servers:   make(map[string]*ServerInstance),
		transfers: make(map[string]*TransferInstance),
	}
}

// === 客户端管理 ===

// CreateClient 创建新的客户端实例
func (m *NetworkManager) CreateClient(name, host, port, protocol string) (*ClientInstance, error) {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	id := fmt.Sprintf("client_%d", time.Now().UnixNano())

	instance := &ClientInstance{
		ID:        id,
		Name:      name,
		Host:      host,
		Port:      port,
		Protocol:  protocol,
		Status:    StatusStopped,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
		Client:    NewClient(),
	}

	// 设置回调
	m.setupClientCallbacks(instance)

	m.clients[id] = instance

	if m.OnClientEvent != nil {
		m.OnClientEvent(instance, "created", nil)
	}

	return instance, nil
}

// StartClient 启动客户端
func (m *NetworkManager) StartClient(id string) error {
	m.mutex.Lock()
	instance, exists := m.clients[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("客户端实例不存在: %s", id)
	}

	if instance.Status == StatusRunning {
		return fmt.Errorf("客户端已经在运行中")
	}

	err := instance.Client.Connect(instance.Host, instance.Port, instance.Protocol)
	if err != nil {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnClientEvent != nil {
			m.OnClientEvent(instance, "error", err.Error())
		}

		return err
	}

	instance.Status = StatusRunning
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnClientEvent != nil {
		m.OnClientEvent(instance, "started", nil)
	}

	return nil
}

// StopClient 停止客户端
func (m *NetworkManager) StopClient(id string) error {
	m.mutex.Lock()
	instance, exists := m.clients[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("客户端实例不存在: %s", id)
	}

	if instance.Status == StatusStopped {
		return nil
	}

	err := instance.Client.Disconnect()
	if err != nil {
		return err
	}

	instance.Status = StatusStopped
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnClientEvent != nil {
		m.OnClientEvent(instance, "stopped", nil)
	}

	return nil
}

// DeleteClient 删除客户端
func (m *NetworkManager) DeleteClient(id string) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	instance, exists := m.clients[id]
	if !exists {
		return fmt.Errorf("客户端实例不存在: %s", id)
	}

	// 先停止客户端
	if instance.Status == StatusRunning {
		instance.Client.Disconnect()
	}

	delete(m.clients, id)

	if m.OnClientEvent != nil {
		m.OnClientEvent(instance, "deleted", nil)
	}

	return nil
}

// GetClient 获取客户端实例
func (m *NetworkManager) GetClient(id string) (*ClientInstance, bool) {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instance, exists := m.clients[id]
	return instance, exists
}

// ListClients 列出所有客户端
func (m *NetworkManager) ListClients() []*ClientInstance {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instances := make([]*ClientInstance, 0, len(m.clients))
	for _, instance := range m.clients {
		instances = append(instances, instance)
	}

	return instances
}

// SendToClient 向客户端发送数据
func (m *NetworkManager) SendToClient(id string, data string) error {
	m.mutex.RLock()
	instance, exists := m.clients[id]
	m.mutex.RUnlock()

	if !exists {
		return fmt.Errorf("客户端实例不存在: %s", id)
	}

	if instance.Status != StatusRunning {
		return fmt.Errorf("客户端未运行")
	}

	return instance.Client.SendString(data)
}

// setupClientCallbacks 设置客户端回调
func (m *NetworkManager) setupClientCallbacks(instance *ClientInstance) {
	instance.Client.OnConnected = func() {
		instance.Status = StatusRunning
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnClientEvent != nil {
			m.OnClientEvent(instance, "connected", nil)
		}
	}

	instance.Client.OnDisconnected = func() {
		instance.Status = StatusStopped
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnClientEvent != nil {
			m.OnClientEvent(instance, "disconnected", nil)
		}
	}

	instance.Client.OnDataReceived = func(data []byte) {
		if m.OnClientEvent != nil {
			m.OnClientEvent(instance, "data_received", string(data))
		}
	}

	instance.Client.OnError = func(err error) {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnClientEvent != nil {
			m.OnClientEvent(instance, "error", err.Error())
		}
	}
}

// === 服务端管理 ===

// CreateServer 创建新的服务端实例
func (m *NetworkManager) CreateServer(name, port, protocol string) (*ServerInstance, error) {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	id := fmt.Sprintf("server_%d", time.Now().UnixNano())

	instance := &ServerInstance{
		ID:        id,
		Name:      name,
		Port:      port,
		Protocol:  protocol,
		Status:    StatusStopped,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
		Server:    NewServer(),
	}

	// 设置回调
	m.setupServerCallbacks(instance)

	m.servers[id] = instance

	if m.OnServerEvent != nil {
		m.OnServerEvent(instance, "created", nil)
	}

	return instance, nil
}

// StartServer 启动服务端
func (m *NetworkManager) StartServer(id string) error {
	m.mutex.Lock()
	instance, exists := m.servers[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("服务端实例不存在: %s", id)
	}

	if instance.Status == StatusRunning {
		return fmt.Errorf("服务端已经在运行中")
	}

	err := instance.Server.Start(instance.Port, instance.Protocol)
	if err != nil {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "error", err.Error())
		}

		return err
	}

	instance.Status = StatusRunning
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnServerEvent != nil {
		m.OnServerEvent(instance, "started", nil)
	}

	return nil
}

// StopServer 停止服务端
func (m *NetworkManager) StopServer(id string) error {
	m.mutex.Lock()
	instance, exists := m.servers[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("服务端实例不存在: %s", id)
	}

	if instance.Status == StatusStopped {
		return nil
	}

	err := instance.Server.Stop()
	if err != nil {
		return err
	}

	instance.Status = StatusStopped
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnServerEvent != nil {
		m.OnServerEvent(instance, "stopped", nil)
	}

	return nil
}

// DeleteServer 删除服务端
func (m *NetworkManager) DeleteServer(id string) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	instance, exists := m.servers[id]
	if !exists {
		return fmt.Errorf("服务端实例不存在: %s", id)
	}

	// 先停止服务端
	if instance.Status == StatusRunning {
		instance.Server.Stop()
	}

	delete(m.servers, id)

	if m.OnServerEvent != nil {
		m.OnServerEvent(instance, "deleted", nil)
	}

	return nil
}

// GetServer 获取服务端实例
func (m *NetworkManager) GetServer(id string) (*ServerInstance, bool) {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instance, exists := m.servers[id]
	return instance, exists
}

// ListServers 列出所有服务端
func (m *NetworkManager) ListServers() []*ServerInstance {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instances := make([]*ServerInstance, 0, len(m.servers))
	for _, instance := range m.servers {
		instances = append(instances, instance)
	}

	return instances
}

// SendToServer 向服务端的所有客户端发送数据
func (m *NetworkManager) SendToServer(id string, data string) error {
	m.mutex.RLock()
	instance, exists := m.servers[id]
	m.mutex.RUnlock()

	if !exists {
		return fmt.Errorf("服务端实例不存在: %s", id)
	}

	if instance.Status != StatusRunning {
		return fmt.Errorf("服务端未运行")
	}

	instance.Server.SendToAll([]byte(data))
	return nil
}

// setupServerCallbacks 设置服务端回调
func (m *NetworkManager) setupServerCallbacks(instance *ServerInstance) {
	instance.Server.OnStarted = func() {
		instance.Status = StatusRunning
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "started", nil)
		}
	}

	instance.Server.OnStopped = func() {
		instance.Status = StatusStopped
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "stopped", nil)
		}
	}

	instance.Server.OnClientConnected = func(conn *Connection) {
		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "client_connected", conn.Address)
		}
	}

	instance.Server.OnClientDisconnected = func(conn *Connection) {
		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "client_disconnected", conn.Address)
		}
	}

	instance.Server.OnDataReceived = func(conn *Connection, data []byte) {
		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "data_received", map[string]interface{}{
				"address": conn.Address,
				"data":    string(data),
			})
		}
	}

	instance.Server.OnError = func(err error) {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnServerEvent != nil {
			m.OnServerEvent(instance, "error", err.Error())
		}
	}
}

// === 转发管理 ===

// CreateTransfer 创建新的转发实例
func (m *NetworkManager) CreateTransfer(name, localHost, localPort, targetHost, targetPort, protocol string) (*TransferInstance, error) {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	id := fmt.Sprintf("transfer_%d", time.Now().UnixNano())

	instance := &TransferInstance{
		ID:               id,
		Name:             name,
		LocalHost:        localHost,
		LocalPort:        localPort,
		TargetHost:       targetHost,
		TargetPort:       targetPort,
		Protocol:         protocol,
		Status:           StatusStopped,
		CreatedAt:        time.Now(),
		UpdatedAt:        time.Now(),
		Transfer:         NewTransfer(),
		Connections:      0,
		BytesTransferred: 0,
	}

	// 设置回调
	m.setupTransferCallbacks(instance)

	m.transfers[id] = instance

	if m.OnTransferEvent != nil {
		m.OnTransferEvent(instance, "created", nil)
	}

	return instance, nil
}

// StartTransfer 启动转发
func (m *NetworkManager) StartTransfer(id string) error {
	m.mutex.Lock()
	instance, exists := m.transfers[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("转发实例不存在: %s", id)
	}

	if instance.Status == StatusRunning {
		return fmt.Errorf("转发已经在运行中")
	}

	err := instance.Transfer.Start(instance.LocalHost, instance.LocalPort, instance.TargetHost, instance.TargetPort, instance.Protocol)
	if err != nil {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnTransferEvent != nil {
			m.OnTransferEvent(instance, "error", err.Error())
		}

		return err
	}

	instance.Status = StatusRunning
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnTransferEvent != nil {
		m.OnTransferEvent(instance, "started", nil)
	}

	return nil
}

// StopTransfer 停止转发
func (m *NetworkManager) StopTransfer(id string) error {
	m.mutex.Lock()
	instance, exists := m.transfers[id]
	m.mutex.Unlock()

	if !exists {
		return fmt.Errorf("转发实例不存在: %s", id)
	}

	if instance.Status == StatusStopped {
		return nil
	}

	err := instance.Transfer.Stop()
	if err != nil {
		return err
	}

	instance.Status = StatusStopped
	instance.Error = ""
	instance.UpdatedAt = time.Now()

	if m.OnTransferEvent != nil {
		m.OnTransferEvent(instance, "stopped", nil)
	}

	return nil
}

// DeleteTransfer 删除转发
func (m *NetworkManager) DeleteTransfer(id string) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()

	instance, exists := m.transfers[id]
	if !exists {
		return fmt.Errorf("转发实例不存在: %s", id)
	}

	// 先停止转发
	if instance.Status == StatusRunning {
		instance.Transfer.Stop()
	}

	delete(m.transfers, id)

	if m.OnTransferEvent != nil {
		m.OnTransferEvent(instance, "deleted", nil)
	}

	return nil
}

// GetTransfer 获取转发实例
func (m *NetworkManager) GetTransfer(id string) (*TransferInstance, bool) {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instance, exists := m.transfers[id]
	return instance, exists
}

// ListTransfers 列出所有转发
func (m *NetworkManager) ListTransfers() []*TransferInstance {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	instances := make([]*TransferInstance, 0, len(m.transfers))
	for _, instance := range m.transfers {
		// 更新统计信息
		if instance.Transfer != nil {
			instance.Connections = int64(instance.Transfer.GetActiveConnections())
			instance.BytesTransferred = instance.Transfer.GetBytesTransferred()
		}
		instances = append(instances, instance)
	}

	return instances
}

// setupTransferCallbacks 设置转发回调
func (m *NetworkManager) setupTransferCallbacks(instance *TransferInstance) {
	instance.Transfer.OnStarted = func() {
		instance.Status = StatusRunning
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnTransferEvent != nil {
			m.OnTransferEvent(instance, "started", nil)
		}
	}

	instance.Transfer.OnStopped = func() {
		instance.Status = StatusStopped
		instance.Error = ""
		instance.UpdatedAt = time.Now()

		if m.OnTransferEvent != nil {
			m.OnTransferEvent(instance, "stopped", nil)
		}
	}

	instance.Transfer.OnDataTransferred = func(bytes int64) {
		if m.OnTransferEvent != nil {
			m.OnTransferEvent(instance, "data_transferred", bytes)
		}
	}

	instance.Transfer.OnError = func(err error) {
		instance.Status = StatusError
		instance.Error = err.Error()
		instance.UpdatedAt = time.Now()

		if m.OnTransferEvent != nil {
			m.OnTransferEvent(instance, "error", err.Error())
		}
	}
}

// GetStats 获取管理器统计信息
func (m *NetworkManager) GetStats() map[string]interface{} {
	m.mutex.RLock()
	defer m.mutex.RUnlock()

	var runningClients, runningServers, runningTransfers int

	for _, instance := range m.clients {
		if instance.Status == StatusRunning {
			runningClients++
		}
	}

	for _, instance := range m.servers {
		if instance.Status == StatusRunning {
			runningServers++
		}
	}

	for _, instance := range m.transfers {
		if instance.Status == StatusRunning {
			runningTransfers++
		}
	}

	return map[string]interface{}{
		"total_clients":     len(m.clients),
		"running_clients":   runningClients,
		"total_servers":     len(m.servers),
		"running_servers":   runningServers,
		"total_transfers":   len(m.transfers),
		"running_transfers": runningTransfers,
	}
}
